/**
 * 
 */
package sii.challenge.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Scanner;

import sii.challenge.main.MainController;
import sii.challenge.modello.Rating;

/**
 * Classe che fornisce un insieme di funzioni di utilita'
 * @author francesco, dario
 *
 */
public class Utils {

	/**
	 * funzione che divide il data set in training set e test set.
	 * Crea tre file:
	 * - test.dat con l'insieme di test,
	 * - user_trainingRatings.dat con l'insieme di training,
	 * - test_mae.dat con la soluzione dei test (utile per calcolare il mae)
	 * @param rapportoTest il rapporto dei dati da utilizzare per il test (es.: 4 = 1/4 = 25%, 10 = 10%)
	 * @param inputFile Il nome del file con il data set completo
	 */
	public static void split(int rapportoTest, String inputFile){
		try {
			File file_input = new File(inputFile);
			FileOutputStream file_training = new FileOutputStream("user_trainingRatings.dat");
			FileOutputStream file_test = new FileOutputStream("test.dat");
			// file con le soluzioni delle predizioni nel test
			FileOutputStream file_test_mae = new FileOutputStream("test_mae.dat");
			PrintStream training = new PrintStream(file_training);
			PrintStream test = new PrintStream(file_test);
			PrintStream test_mae = new PrintStream(file_test_mae);
			Scanner scan = new Scanner(file_input);
			scan.useDelimiter("\n");
			int n = 0;
			while(scan.hasNext()) {
				// record di test
				if (n == rapportoTest){
					n = 0;
					Scanner scan2 = new Scanner(scan.next().trim());
					scan2.useDelimiter(",");
					while (scan2.hasNext()) {
						// scrivo sul file di test gli id...
						test.print(scan2.nextInt());
						test.print(",");
						test.println(scan2.nextInt());
						// ...e sul test_mae la soluzione 
						test_mae.println(scan2.nextInt());
					}
					scan2.close();
				}
				// training
				else{
					training.println(scan.next());
				}
				n++;
			}
			scan.close();
			training.close();
			test.close();
			test_mae.close();

		} catch(Exception e) {
			System.out.println(e.toString());
		}
	}

	/**
	 * funzione che mentre calcola i rating predetti calcola e stampa la MAE
	 * utilizzando il file file_test_mae.dat
	 * @param inputFile Il nome del file con i rating da predire
	 * @param outputFile Il nome del file su cui scrivere le predizioni
	 */
	public static void calcola_mae(String inputFile, String outputFile){
		File file_input = new File(inputFile);
		MainController controller = MainController.getInstance();
		
		double mae = 0;
		int n = 0;

		try {
			FileOutputStream file_output = new FileOutputStream(outputFile);
			PrintStream output = new PrintStream(file_output);
			Scanner scan = new Scanner(file_input);
			Scanner scanMae = new Scanner(new File("test_mae.dat")); //scanMae.useDelimiter("\n");
			scan.useDelimiter("\n");
			int riga=1;
			System.out.println("Mae:");
			while(scan.hasNext()) {
				n++;
				Scanner scan2 = new Scanner(scan.next().trim());
				scan2.useDelimiter(",");
				while (scan2.hasNext()) {
					int idUtente = scan2.nextInt();
					int idProfile = scan2.nextInt();
					Rating rat = controller.getRatingPredettoUserItemCombined(idUtente, idProfile);
					output.println(rat.getRatingValue());
					//leggo il valore vero:
					int ratingVero = scanMae.nextInt(); 
					mae += Math.abs(rat.getRatingValue() - ratingVero);
					System.out.println(++riga+" "+mae/n + "\tRating calcolato:\t"+rat.getRatingValue()+"\tRating vero:\t"+ratingVero);
				}
				scan2.close();
			}
			scan.close();
			output.close();

		} catch(Exception e) {
			System.out.println(e.toString());
		}
	}

}
